package com.ruoyi.wechat.service.impl;

import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.ruoyi.wechat.config.TaskExcutor;
import com.ruoyi.wechat.domain.MsgReplyRule;
import com.ruoyi.wechat.domain.WxWxMsg;
import com.ruoyi.wechat.service.MsgReplyRuleService;
import com.ruoyi.wechat.service.MsgReplyService;
import com.ruoyi.wechat.service.WxWxMsgService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.kefu.WxMpKefuMessage;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @Author: yan
 * @Description: 微信公众号消息处理
 * @Date: 2022-07-18
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class MsgReplyServiceImpl implements MsgReplyService {
    @Resource
    MsgReplyRuleService msgReplyRuleService;
    private final WxMpService wxMpService;
    private final Long autoReplyInterval = 1000L;
    @Resource
    WxWxMsgService wxMsgService;

    /**
     * 根据规则配置通过微信客服消息接口自动回复消息
     *
     * @param appid      公众号appid
     * @param exactMatch 是否精确匹配
     * @param toUser     用户openid
     * @param keywords   匹配关键词
     * @return 是否已自动回复，无匹配规则则不自动回复
     */
    @Override
    public boolean tryAutoReply(String appid, boolean exactMatch, String toUser, String keywords) {
        log.info("自动回复的参数:appid={},toUser={},keywords={}", appid, toUser, keywords);
        try {
            List<MsgReplyRule> rules = msgReplyRuleService.getMatchedRules(appid, exactMatch, keywords);
            if (rules.isEmpty()) {
                return false;
            }
            long delay = 0;
            for (MsgReplyRule rule : rules) {
                TaskExcutor.schedule(() -> {
                    wxMpService.switchover(appid);
                    this.reply(toUser, rule.getReplyType(), rule.getReplyContent());
                    log.info("自动回复的参数:消息类型={},toUser={},回复内容={}", rule.getReplyType(), toUser, rule.getReplyContent());
                }, delay, TimeUnit.MILLISECONDS);
                delay += autoReplyInterval;
            }
            return true;
        } catch (Exception e) {
            log.error("自动回复出错：", e);
        }
        return false;
    }

    @Override
    public void replyText(String toUser, String content) throws WxErrorException {
        wxMpService.getKefuService().sendKefuMessage(WxMpKefuMessage.TEXT().toUser(toUser).content(content).build());
        JSONObject json = new JSONObject().put("content", content);
        wxMsgService.addWxMsg(WxWxMsg.buildOutMsg(WxConsts.KefuMsgType.TEXT, toUser, json));
    }

    @Override
    public void replyImage(String toUser, String mediaId) throws WxErrorException {
        wxMpService.getKefuService().sendKefuMessage(WxMpKefuMessage.IMAGE().toUser(toUser).mediaId(mediaId).build());

        JSONObject json = new JSONObject().put("mediaId", mediaId);
        wxMsgService.addWxMsg(WxWxMsg.buildOutMsg(WxConsts.KefuMsgType.IMAGE, toUser, json));
    }

    @Override
    public void replyVoice(String toUser, String mediaId) throws WxErrorException {
        wxMpService.getKefuService().sendKefuMessage(WxMpKefuMessage.VOICE().toUser(toUser).mediaId(mediaId).build());

        JSONObject json = new JSONObject().put("mediaId", mediaId);
        wxMsgService.addWxMsg(WxWxMsg.buildOutMsg(WxConsts.KefuMsgType.VOICE, toUser, json));
    }

    @Override
    public void replyVideo(String toUser, String mediaId) throws WxErrorException {
        wxMpService.getKefuService().sendKefuMessage(WxMpKefuMessage.VIDEO().toUser(toUser).mediaId(mediaId).build());

        JSONObject json = new JSONObject().put("mediaId", mediaId);
        wxMsgService.addWxMsg(WxWxMsg.buildOutMsg(WxConsts.KefuMsgType.VIDEO, toUser, json));
    }

    @Override
    public void replyMusic(String toUser, String musicInfoJson) throws WxErrorException {
        JSONObject json = JSONUtil.parseObj(musicInfoJson);
        wxMpService.getKefuService().sendKefuMessage(
                WxMpKefuMessage.MUSIC().toUser(toUser)
                        .musicUrl(json.getStr("musicurl"))
                        .hqMusicUrl(json.getStr("hqmusicurl"))
                        .title(json.getStr("title"))
                        .description(json.getStr("description"))
                        .thumbMediaId(json.getStr("thumb_media_id"))
                        .build());

        wxMsgService.addWxMsg(WxWxMsg.buildOutMsg(WxConsts.KefuMsgType.IMAGE, toUser, json));
    }

    /**
     * 发送图文消息（点击跳转到外链） 图文消息条数限制在1条以内
     *
     * @param toUser
     * @param newsInfoJson
     * @throws WxErrorException
     */
    @Override
    public void replyNews(String toUser, String newsInfoJson) throws WxErrorException {
        WxMpKefuMessage.WxArticle wxArticle = JSONUtil.toBean(newsInfoJson, WxMpKefuMessage.WxArticle.class);
        List<WxMpKefuMessage.WxArticle> newsList = new ArrayList<WxMpKefuMessage.WxArticle>() {{
            add(wxArticle);
        }};
        wxMpService.getKefuService().sendKefuMessage(WxMpKefuMessage.NEWS().toUser(toUser).articles(newsList).build());

        wxMsgService.addWxMsg(WxWxMsg.buildOutMsg(WxConsts.KefuMsgType.NEWS, toUser, JSONUtil.parseObj(newsInfoJson)));
    }

    /**
     * 发送图文消息（点击跳转到图文消息页面） 图文消息条数限制在1条以内
     *
     * @param toUser
     * @param mediaId
     * @throws WxErrorException
     */
    @Override
    public void replyMpNews(String toUser, String mediaId) throws WxErrorException {
        wxMpService.getKefuService().sendKefuMessage(WxMpKefuMessage.MPNEWS().toUser(toUser).mediaId(mediaId).build());

        JSONObject json = new JSONObject().put("mediaId", mediaId);
        wxMsgService.addWxMsg(WxWxMsg.buildOutMsg(WxConsts.KefuMsgType.MPNEWS, toUser, json));
    }

    @Override
    public void replyWxCard(String toUser, String cardId) throws WxErrorException {
        wxMpService.getKefuService().sendKefuMessage(WxMpKefuMessage.WXCARD().toUser(toUser).cardId(cardId).build());

        JSONObject json = new JSONObject().put("cardId", cardId);
        wxMsgService.addWxMsg(WxWxMsg.buildOutMsg(WxConsts.KefuMsgType.WXCARD, toUser, json));
    }

    @Override
    public void replyMiniProgram(String toUser, String miniProgramInfoJson) throws WxErrorException {
        JSONObject json = JSONUtil.parseObj(miniProgramInfoJson);
        wxMpService.getKefuService().sendKefuMessage(
                WxMpKefuMessage.MINIPROGRAMPAGE()
                        .toUser(toUser)
                        .title(json.getStr("title"))
                        .appId(json.getStr("appid"))
                        .pagePath(json.getStr("pagepath"))
                        .thumbMediaId(json.getStr("thumb_media_id"))
                        .build());

        wxMsgService.addWxMsg(WxWxMsg.buildOutMsg(WxConsts.KefuMsgType.IMAGE, toUser, json));
    }

    @Override
    public void replyMsgMenu(String toUser, String msgMenusJson) throws WxErrorException {
        JSONObject json = JSONUtil.parseObj(msgMenusJson);
        List<WxMpKefuMessage.MsgMenu> msgMenus = JSONUtil.toList(JSONUtil.parseArray(json.getStr("list")), WxMpKefuMessage.MsgMenu.class);
        wxMpService.getKefuService().sendKefuMessage(
                WxMpKefuMessage.MSGMENU()
                        .toUser(toUser)
                        .headContent(json.getStr("head_content"))
                        .tailContent(json.getStr("tail_content"))
                        .msgMenus(msgMenus).build());

        wxMsgService.addWxMsg(WxWxMsg.buildOutMsg(WxConsts.KefuMsgType.IMAGE, toUser, json));
    }

}
